home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Gigarom 1
/
Gigarom Macintosh Archives (Quantum Leap)(CDRM1080320)(1993).iso
/
FILES
/
HYP
/
E-G
/
GetFileXFCN.cpt
/
FileName.p
next >
Wrap
Text File
|
1989-02-26
|
6KB
|
210 lines
{
Name: “FileName” -- a HyperCard "XFCN" (External Function) resource
Written By: Steve Maller
Apple Computer Training Support
Copyright © 1987 Apple Computer
AppleLink: MALLER1
Saturday, August 22, 1987
Language: MPW Pascal
To build: pascal FileName.p
link -m ENTRYPOINT -rt XFCN=913 -sn Main=FileName ∂
-t STAK -c WILD ∂
FileName.p.o ∂
hd:dev:mpw:libraries:Interface.o ∂
hd:dev:mpw:PLibraries:Paslib.o ∂
-o "hd:hyper:hypercard stacks:TestXFCN"
Usage: FileName("fileType") -- "fileType" is optional
Examples: FileName("STAK") -- limits list to HyperCard Stacks
FileName("TEXT") -- limits list to text files
FileName("APPL") -- limits list to applications
FileName() -- lists ALL files
Result: The full pathname of the selected file.
For example, if you selected the file "Address Stack" which is
in the folder "My Stacks" in the folder "HyperCard" on the
disk "HD" the result is:
HD:HyperCard:My Stacks:Address Stack
If the user clicks “Cancel” an empty string is returned.
Warning: A word of caution: the Mac's file system can NOT accept
pathnames longer than 255 characters. Be careful...
Script
Example: on mouseUp
put FileName("TEXT") into theFile
if theFile is not empty then
open file theFile
read from file theFile for 2000
put it into bkgnd field 1
close file theFile
end if
end mouseUp
Why? You must access files in HyperCard by their full pathname.
Unfortunately, HyperCard offers you no clear way of finding
out what that full name is. If files are on a hard disk, it
can be a real pain to remember the entire pathname. This
function simplifies that task for both the stackware developer
and the end user.
Thanks to: Ted Kaehler, Dan Winkler, and Bill Atkinson - my hero!
}
{$S FileName }
UNIT Snoopy_Vs_TheRedBaron; { obviously this is irrelevant }
INTERFACE
USES
{$LOAD HD:Hyper:XCMDs:PasSymDump}
MemTypes, QuickDraw, OSIntf, ToolIntf, PackIntf, HyperXCmd;
PROCEDURE EntryPoint(paramPtr: XCmdPtr);
IMPLEMENTATION
TYPE
Str31 = String[31];
PROCEDURE FileName(paramPtr: XCmdPtr);
FORWARD;
PROCEDURE EntryPoint(paramPtr: XCmdPtr);
BEGIN
FileName(paramPtr);
END;
PROCEDURE FileName(paramPtr: XCmdPtr);
VAR
myWDPB: WDPBPtr; { some variants of the same animal }
myCPB: CInfoPBPtr;
myPB: HParmBlkPtr;
fullPathName: Str255;
numTypes: Integer;
reply: SFReply;
typeList: SFTypeList;
{$I XCmdGlue.inc }
FUNCTION TheyChoseAFile: Boolean;
VAR
pt: Point;
BEGIN
TheyChoseAFile := FALSE;
pt.v := 60;
pt.h := 82;
SFGetFile(pt, '', NIL, numTypes, typeList, NIL, reply);
{ have 'em pick a file }
IF reply.good THEN { if they didn't choose Cancel }
BEGIN
TheyChoseAFile := TRUE;
fullPathName := reply.fName; { start the ball rolling }
END;
END;
PROCEDURE BuildThePathName;
VAR
name: Str255;
err: Integer;
BEGIN
name := ''; { start with an empty name }
myPB^.ioNamePtr := @name; { we want the Volume name }
myPB^.ioCompletion := pointer(0);
myPB^.ioVRefNum := reply.vRefNum; { returned from SFGetFile }
myPB^.ioVolIndex := 0; { use the vRefNum and name }
err := PBHGetVInfo(myPB, FALSE); { fill in the Volume info }
IF err <> noErr THEN
Exit(FileName);
{ Now we need the Working Directory (WD) information because we're going
to step backwards from the file through all of the the folders until
we reach the root directory }
myWDPB^.ioVRefNum := reply.vRefNum; { this got set to 0 above }
myWDPB^.ioWDProcID := 0; { use the vRefNum }
myWDPB^.ioWDIndex := 0; { we want ALL directories }
err := PBGetWDInfo(myWDPB, FALSE); { do it }
IF err <> noErr THEN
Exit(FileName);
myCPB^.ioFDirIndex := - 1; { use the ioDirID field only }
myCPB^.ioDrDirID := myWDPB^.ioWDDirID;{ info returned above }
err := PBGetCatInfo(myCPB, FALSE); { do it }
IF err <> noErr THEN
Exit(FileName);
{ Here starts the real work - start to climb the tree by continually
looking in the ioDrParId field for the next directory above until we
fail... }
myCPB^.ioDrDirID := myCPB^.ioDrParId; { the first folder}
fullPathName := Concat(myCPB^.ioNamePtr^, ':', reply.fName);
REPEAT
myCPB^.ioDrDirID := myCPB^.ioDrParId;
err := PBGetCatInfo(myCPB, FALSE); { the next level }
{ Be careful of an error returned here - it means the user chose a file
on the desktop level of this volume. If this is the case, just stop
here and return "VolumeName:FileName", otherwise loop until failure }
IF err = noErr THEN
fullPathName := Concat(myCPB^.ioNamePtr^, ':', fullPathName);
UNTIL err <> noErr;
END; { PROCEDURE BuildThePathName }
BEGIN { PROCEDURE FileName }
{ First we allocate some memory in the heap for the parameter block. This
could in theory work on the stack, but in reality it makes no difference
as we're entirely modal (ugh) here... }
fullPathName := '';
myCPB := CInfoPBPtr(NewPtr(SizeOf(HParamBlockRec)));
IF ord4(myCPB) <= 0 THEN
Exit(FileName); { Rats! Bill didn't leave enough room }
myWDPB := WDPBPtr(myCPB); { icky Pascal type coercions follow }
myPB := HParmBlkPtr(myCPB);
numTypes := 1; { for SFGetFile }
WITH paramPtr^ DO
BEGIN
IF paramCount = 0 THEN
numTypes := - 1 { FileName() - get all files }
ELSE
BlockMove(params[1]^, @typeList[0], 4);
{ FileName("TYPE") }
IF TheyChoseAFile THEN
BuildThePathName;
{ PasToZero is very interesting - it is a HyperTalk command
that you can actually call from OUTSIDE of HyperCard.
You need it because HyperCard uses C format strings with
no length byte; they are terminated by a null byte. They are
actually HANDLES to C format strings. Nice work, Dan! }
returnValue := PasToZero(fullPathName);
END; { WITH paramPtr^ DO }
DisposPtr(pointer(myCPB)); { Clean Up Your Heap! }
END; { PROCEDURE FileName }
END.